package com.rytong.tools.ui;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.webkit.JsResult;
import android.webkit.URLUtil;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.rytong.tools.crypto.Base64;
import com.rytong.tools.datastorage.SqlDb;
import com.rytong.tools.offstore.OffStoreDownload;
import com.rytong.tools.ui.jsfunction.EmpAccelerometer;
import com.rytong.tools.ui.jsfunction.EmpAudio;
import com.rytong.tools.ui.jsfunction.EmpCamera;
import com.rytong.tools.ui.jsfunction.EmpContact;
import com.rytong.tools.ui.jsfunction.EmpFile;
import com.rytong.tools.ui.jsfunction.EmpGPS;
import com.rytong.tools.ui.jsfunction.EmpVideo;
import com.rytong.tools.utils.Utils;

public class LPWebView extends Component {
    final String SMSERRORUNKNOWN_ERROR = "1";
    final String SMSERRORNOT_SUPPORT_ERROR = "2";
    final String SMSERRORSEND_FAIL_ERROR = "3";
    final String SMSERRORTIME_OUT_ERROR = "4";

    final String DatabaseErrorUNKNOWN_ERROR = "1";
    final String DatabaseErrorADD_FAIL_ERROR = "2";
    final String DatabaseErrorGET_FAIL_ERROR = "3";
    final String DatabaseErrorINSERT_FAIL_ERROR = "4";
    final String DatabaseErrorUPDATE_FAIL_ERROR = "5";
    final String DatabaseErrorOPEN_FAIL_ERROR = "6";
    final String DatabaseErrorCLOSE_FAIL_ERROR = "7";
    final String DatabaseErrorEXEC_FAIL_ERROR = "8";

    private EmpAccelerometer accelerometer_;
    private EmpAudio la_;
    private EmpFile lf_;
    private EmpVideo lv_;
    private SqlDb edb_;
    private EmpCamera camera_;
    private EmpContact contact_;
    private EmpGPS gps_;
    private Activity activity_;
	private WebSettings mySettings;
     
    
    public class MyLPWebView extends WebView implements CompositedComponent {
        
        public MyLPWebView(Context context) {
            super(context);
            getSettings().setJavaScriptEnabled(true);
            
            accelerometer_ = new EmpAccelerometer();
            requestFocus();
            la_ = new EmpAudio();
            lf_ = new EmpFile();
            lv_ = new EmpVideo();
            edb_ = new SqlDb(context, "database.sql", null, 1);
            camera_ = new EmpCamera();
            contact_ = new EmpContact();
            gps_ = new EmpGPS();
        }
    
        @Override
        public Component composited() {
            return LPWebView.this;
        }
    }
    
    @Override
    public void initRealView(final Activity activity, String value) {
        // TODO Auto-generated method stub
    	activity_ = activity;
        realView_ = new MyLPWebView(activity);
        final MyLPWebView ewv = (MyLPWebView) realView_;
        printMessage(ewv);
        openCamera(ewv);
        getCurrentLocation(ewv, activity);
        initAccelerometer(ewv);
        sendSms(ewv);
        initContactTemp(activity, ewv);
        initContact(ewv);
        initDevice(ewv);
        initHttp(ewv);        
        initFile(ewv);
        initVideo(ewv);
        initAudio(ewv);
        initDatabase(ewv);
        ewv.setWebViewClient(client);
        setConfig(ewv);
        ewv.setWebChromeClient(new WebChromeClient(){
        	
        	    @Override
        	    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
        	        // TODO Auto-generated method stub
        	        //js:   alert();
        	        new AlertDialog.Builder(activity)
        	        .setTitle("提示")
        	        .setMessage(message)
        	        .setCancelable(false)
        	        .setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener(){
        	
        	            public void onClick(DialogInterface dialog, int which) {
        	                // TODO Auto-generated method stub
        	                result.confirm();
        	            }
        	            
        	        })
        	        .show();
        	        return true;
        	    }
        	
        	    @Override
        	    public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
        	        // TODO Auto-generated method stub
        	        //js:  window.confirm();
        	        new AlertDialog.Builder(activity)
        	        .setTitle("提示")
        	        .setMessage(message)
        	        .setCancelable(false)
        	        .setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener(){
        	
        	            @Override
        	            public void onClick(DialogInterface dialog, int which) {
        	                // TODO Auto-generated method stub
        	                result.confirm();
        	            }
        	            
        	        })
        	        .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
        	            
        	            @Override
        	            public void onClick(DialogInterface dialog, int which) {
        	                // TODO Auto-generated method stub
        	                result.cancel();
        	            }
        	        })
        	        .show();
        	        return true;
        	    }
        	    
        	});
        
    }
    
	protected void setConfig(WebView ewv) {
		mySettings = ewv.getSettings();
		mySettings.setSupportZoom(true);
		mySettings.setJavaScriptEnabled(true);
		mySettings.setBuiltInZoomControls(true);
		mySettings.setLoadsImagesAutomatically(true);
	}
    
	WebViewClient client = new WebViewClient() {
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			view.loadUrl(url);
			return true;
		}

		public void onPageFinished(WebView view, String url) {
		}

		public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
		}
		
		public void onReceivedSslError(WebView view, android.webkit.SslErrorHandler handler, android.net.http.SslError error) {
			handler.proceed();
		};
	};

    public void mouldH() throws Exception {
        super.mouldH();
        getLocalRes();
    }

    private void getLocalRes() {
        // TODO Auto-generated method stub
        String res = getPropertyByName("url").trim();
        if (res.startsWith("local:")) {
            res = res.substring(6);
            byte[] byt = Utils.readFile(OffStoreDownload.FILEROOT.concat(OffStoreDownload.PLUGROOT).concat(res));
            if (null != byt) {
                res = new String((byte[]) byt);
            }
            //加载本地文件
            ((MyLPWebView) realView_).loadDataWithBaseURL(null , res, "text/html", "utf-8", "");
        } else {
            loadUrl(res);
        }
    }

    public void loadUrl(String url) {// ,String mimeType) {
    	MyLPWebView temp = (MyLPWebView) realView_;
    	if (null != temp && URLUtil.isNetworkUrl(url)) {
    	    temp.loadUrl(url);
    	    temp.invalidate();
    	    // temp.loadData(url, mimeType, "utf-8");
    	    // temp.loadDataWithBaseURL(null, url, null, "utf-8", null);
        }
    }

    /**
     * 包含当前设备常用信息
     * 
     * @param ewv
     */
    private void initDevice(MyLPWebView ewv) {
        
        String deviceJStr = "javascript: var device = new Object(); device.name = '".concat(Utils.getDeviceName())
                .concat("'; device.platform = '").concat(Utils.getPlayform())
                .concat("'; device.version = '").concat(Utils.getVersion())
                .concat("'; device.uuid = '").concat(Utils.getUUID())
                .concat("'; " ); 
        ewv.loadUrl(deviceJStr);
    }
    
    /**
     * 在提供的数据库中执行sql语句
     * 
     * @param ewv
     */
    private void initDatabase(final MyLPWebView ewv) {
        // TODO Auto-generated method stub
        ewv.addJavascriptInterface(new Object() {

            public void exec(Object handle, String sql) {
                edb_.exec(handle, sql);
            }

            public void close(String name) {
                edb_.close(name);
            }

            public Object open(String name) {
                return edb_.open(name);
            }

            public void updateData(String key, String value, String callback) {
                edb_.updateData(ewv, key, value, callback);
            }

            public void insertData(String key, String value, String callback) {
                edb_.insertData(ewv, key, value, callback);
            }

            public void getData(String key, String callback) {
                edb_.getData(ewv, key, callback);
            }

            public void addData(String key, String value, String callback) {
                edb_.addData(ewv, key, value, callback);
            }

        }, "database");
    }

    /**
     * 加载音频文件。 注：应该优先检查插件下载路径下（或数据库中,有客户端平台可能保存在数据库中）是否存在我们读取的文件，如果不存在，再查找离线资源下载路径下是否已有我们要读取的资源文件，如果不存在再继续查找file:write()
     * 方法操作的本地路径是否存在，最后才查找本地安装包中的自带资源文件
     * 
     * @param ewv
     */
    private void initAudio(final MyLPWebView ewv) {
        // TODO Auto-generated method stub
        ewv.addJavascriptInterface(new Object() {

            public void setVolume(float i, String callback) {
                la_.setVolume(ewv, i, callback);
            }

            public void getVolume(String callback) {
            	la_.getVolume(ewv , callback);
            }

            public void getMinVolume(String callback) {
                la_.getMinVolume(ewv, callback);
            }

            public void getMaxVolume(String callback) {
                la_.getMaxVolume(ewv, callback);
            }

            public void resume() {
                la_.resume();
            }

            public void pause() {
                la_.pause();
            }

            public void load(String string , String callback) {
            	la_.load(ewv , string , callback);
            }

            public void dispose() {
                la_.dispose();
            }

            public void play(int i) {
                la_.play(i);
            }

            public void stop() {
                la_.stop();
            }

        }, "EMPAudio");
        
        ewv.loadUrl("javascript:" +
                "function Audio(path, callback) { EMPAudio.load(path, callback); };  " +
                "Audio.prototype.play = function(count){ EMPAudio.play(count); }; " +
                "Audio.prototype.stop = function(){ EMPAudio.stop(); }; " +
                "Audio.prototype.pause = function(){ EMPAudio.pause(); }; " +
                "Audio.prototype.resume = function(){ EMPAudio.resume(); }; " +
                "Audio.prototype.dispose = function(){ EMPAudio.dispose(); }; " +
                "Audio.prototype.getMaxVolume = function(maxvolcallback){ EMPAudio.getMaxVolume(maxvolcallback); }; " +
                "Audio.prototype.getMinVolume = function(minvolcallback){ EMPAudio.getMinVolume(minvolcallback); }; " +
                "Audio.prototype.getVolume = function(volumecallback){ EMPAudio.getVolume(volumecallback); }; " +
                "Audio.prototype.setVolume = function(volume , volumecallback){ EMPAudio.setVolume(volume , volumecallback); }; ");

    }

    /**
     * 加载视频文件。 注：应该优先检查插件下载路径下（或数据库中,有客户端平台可能保存在数据库中）是否存在我们读取的文件，如果不存在，再查找离线资源下载路径下是否已有我们要读取的资源文件，如果不存在再继续查找file:write()
     * 方法操作的本地路径是否存在，最后才查找本地安装包中的自带资源文件。
     * 
     * @param ewv
     */
    private void initVideo(MyLPWebView ewv) {
        // TODO Auto-generated method stub
        ewv.addJavascriptInterface(new Object() {

            public Object load(String string) {
                return lv_.load(string);
            }

            public void pause() {
                lv_.pause();
            }

            public void dispose() {
                lv_.dispose();
            }

            public void play() {
                lv_.play();
            }

            public void resume() {
                lv_.resume();
            }

            public void stop() {
                lv_.stop();
            }

        }, "EMPVideo");
        ewv.loadUrl("javascript:Video = function(path, callback) { EMPVideo.load(path);callback();  this.paly = function() { EMPVideo.play();} this.stop = function() { EMPVideo.stop();} this.pause = function() { EMPVideo.pause();} this.resume = function() { EMPVideo.resume();} this.dispose = function() { EMPVideo.dispose();}}; ");
    }

    /**
     * 判断给定名称的文件是否存在
     * 注：应该优先检查插件下载路径下（或数据库中,有客户端平台可能保存在数据库中）是否存在我们读取的文件，如果不存在，再查找离线资源下载路径下是否已有我们要读取的资源文件，如果不存在再继续查找file:write
     * ()方法操作的本地路径是否存在，最后才查找本地安装包中的自带资源文件。
     * 
     * @param ewv
     */
    private void initFile(final MyLPWebView ewv) {
        // TODO Auto-generated method stub
        ewv.addJavascriptInterface(new Object() {

            public void isExist(String name, String Callback) {
                lf_.isExist(ewv, name, Callback);
            }

            public void remove(String name, String callback) {
                lf_.remove(ewv, name, callback);
            }

            public void read(String name, String type, String Callback) {
                lf_.read(ewv, name, type, Callback);
            }

            public void write(String name, String data, String callback) {
                lf_.write(ewv, name, data, callback);
            }
        }, "file");
    }

    /**
    * 
    * @param ewv
    * @param activity
    */
    private void initHttp(MyLPWebView ewv) {
       
       initHttpBackup(ewv);
       
       String httpJStr = "javascript: var http = new Object(); http.connectType = '".concat(Utils.connectType(activity_))
               .concat("';  var callbackfun = ''; " )
               .concat(" http.isReachable = function(url,callback){ httpbackup.isReachable(url, callback); }"); 
       ewv.loadUrl(httpJStr);
       
    }
    
    /**
     * 该方法还需要考虑wap情况，有待完善
     * 
     * @param ewv
     * @param string
     *            服务地址（域名或IP）
     */
    private void initHttpBackup(final MyLPWebView ewv) {
        // TODO Auto-generated method stub
        ewv.addJavascriptInterface(new Object() {

        	public void isReachable(String url, String callback) {
        		    String errorCode = "0";
        		    boolean isReach = true;                
        		try {
        			if(!TextUtils.isEmpty(url)){
        				url = url.trim();
        				    
        				URL connector = new URL(url);
        				HttpURLConnection hc = (HttpURLConnection) connector.openConnection();
        				int code = 0;
        				code = hc.getResponseCode();
        				if (code != 200) {
        				    errorCode = String.valueOf(code);
        				    isReach = false;
        				}                    
        		    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                	errorCode = "1";
                	isReach = false;                    
                	Utils.printException(e);
                }
        		
        		if(!TextUtils.isEmpty(callback)){
        			    String params = "true";
        			    if(!isReach){
        			        params = "false";
        			    }
        			    final String callbackfun = "javascript:".concat("var isreach = ").concat(callback).concat(";  isreach(").concat(errorCode)
        			            .concat(","+ params +");");
        			    
        			    activity_.runOnUiThread(new Runnable(){
        			
        			        @Override
        			        public void run() {
        			            ewv.loadUrl(callbackfun);
        			        }
        			        
        			    });
        			    
        			}
            }

        }, "httpbackup");   
    }

    /**
     * 打开手机通讯录
     * 
     * @param ewv
     */
    private void initContact(final MyLPWebView ewv) {
        // TODO Auto-generated method stub
        String personObject = "Persion = function(firstName, middleName, lastName, phoneNumber, email, address) {this.firstName = firstName;  this.middleName = middleName;this.lastName = lastName; this.phoneNumber = phoneNumber; this.email = email; this.address = address};";
        ewv.loadUrl("javascript:".concat(personObject));
        ewv.loadUrl("javascript:contact = function() { }; contact.add = function(array, callback) {for(i=0; i<array.length;i++){ contactTemp.add(array[i].firstName,array[i].middleName,array[i].lastName,array[i].phoneNumber,array[i].email,array[i].address,callback);}}; contact.open = function(callback) {contactTemp.open(callback);}; contact.delete = function(array, callback) {for(i=0; i<array.length;i++){ contactTemp.add(array[i].firstName,array[i].middleName,array[i].lastName,array[i].phoneNumber,array[i].email,array[i].address,callback);}};");
    }

    /**
     * 打开手机通讯录
     * 
     * @param ewv
     */
    private void initContactTemp(final Activity activity, final MyLPWebView ewv) {
        // TODO Auto-generated method stub
        ewv.addJavascriptInterface(new Object() {

            public void add(String firstname, String middlename, String lasetname, String phoneNum, String email,
                    String address, String callback) {
                contact_.add(firstname, middlename, lasetname, phoneNum, email, address);
                ewv.loadUrl("javascript:".concat(callback).concat("();"));
            }

            public void open(String callback) {
                contact_.open(activity, ewv, callback);
            }

            public void delete(String firstname, String middlename, String lasetname, String phoneNum, String email,
                    String address, String callback) {
                contact_.delete(activity, firstname, middlename, lasetname, phoneNum, email, address);
                ewv.loadUrl("javascript:".concat(callback).concat("();"));
            }
        }, "contactTemp");
    }

    /**
     * 发送短信功能
     * 
     * @param ewv
     */
    private void sendSms(final MyLPWebView ewv) {
        // TODO Auto-generated method stub
        ewv.addJavascriptInterface(new Object() {

        	public void send(String phoneNum, String content, String callback) {
        		    
        		   String errorCode = Utils.sendSms(phoneNum, content);
        		    
        		    if(!TextUtils.isEmpty(callback)){
        		        callback = "var sendsms = " + callback + ";  sendsms(" + errorCode +");";
        		        ewv.loadUrl("javascript:".concat(callback));
        		    }            
            }

        }, "sms");
    }

    /**
     * 开启重力感应
     * 
     * @param ewv
     */
    private void initAccelerometer(final MyLPWebView ewv) {
        // TODO Auto-generated method stub
        ewv.addJavascriptInterface(new Object() {

            public void startAccelerometer(String Callback, float interval) {
                accelerometer_.startAccelerometer(ewv, interval, Callback);
            }

            public void setCallback(String fun) {
                ewv.loadUrl("javascript:".concat(fun).concat("()"));
            }

            public void setAccelerometerInterval(int time) {
                accelerometer_.setAccelerometerInterval(time);
            }

            public void stopAccelerometer(String callback) {
                accelerometer_.stopAccelerometer(ewv, callback);
            }
        }, "accelerometer");
    }

    /**
     * 获取当前设备的GPS坐标位置
     * 
     * @param ewv
     * 
     * @param string
     * @param string2
     * @param 精度
     */
    private void getCurrentLocation(final MyLPWebView ewv, final Activity activity) {
        // TODO Auto-generated method stub

        ewv.addJavascriptInterface(new Object() {
            public void getCurrentLocation(String Callback, double accuracy) {
                gps_.getCurrentLocation(ewv, activity, Callback, accuracy);
            }

        }, "geolocation");
    }

    /**
     * 打开设备的默认摄像头
     * 
     * @param ewv
     * @param 开启失败后回调的方法
     * @param 开启成功后回调的方法
     */
    private void openCamera(final MyLPWebView ewv) {
        ewv.addJavascriptInterface(new Object() {

            public void open(final String callback) {

                ((BaseView) getActivity()).cameraHandler_ = new Handler() {

                    public void handleMessage(Message msg) {
                        switch (msg.what) {
                        case 1:// 成功
                        	if(!TextUtils.isEmpty(callback)){
                        		try{
                        		    byte[] buffer = Utils.readFile(camera_.imgPath);
                        		    if(buffer != null){
                        		        String imgData = Base64.decodeToString(new String(buffer,"UTF-8"));
                        		        if(!TextUtils.isEmpty(imgData)){
                        		            ewv.loadUrl("javascript:".concat("var cameracallback = ").concat(callback).concat("; ")
                        		                .concat(" cameracallback(0 , '").concat(imgData).concat("');"));
                        		        }
                        		    }
                        		}catch(Exception e){
                        		    Utils.printException(e);
                        		}
                        	}
                            break;
                        case 2:// 失败
                        	if(!TextUtils.isEmpty(callback)){
                        		ewv.loadUrl("javascript:".concat("var cameracallback = ").concat(callback).concat("; ")
                        		    .concat(" cameracallback(1 , '');"));
                        	}
                            break;
                        default:
                            break;
                        }
                    }
                };

                camera_.open(ewv, callback);
            }

        }, "camera");

    }
    
    /**
     * 打印
     * @param ewv
     * */
    private void printMessage(MyLPWebView ewv) {
        // TODO Auto-generated method stub
        // 自定义打印方法，用来监测自定义的JavaScript执行情况
        ewv.addJavascriptInterface(new Object() {
            public void print(String o) {
                Utils.printOutToConsole(o);
            }

        }, "System");
    }
}
